基础类型
any 任何类型
number 数字类型
string 字符串
boolean 布尔值
Array 数组 各类型元素相同 例如 any[] 或 Array
Tuple 元组 各类型元素不同
enum 枚举
void 函数无返回值
null 空
undefined 未定义
never 永远不存在值的类型
自定义类型
自定义类型 type xxx = number | string
字符串字面量类型 type xxx = ‘click’ | ‘scroll’ …
变量声明 1 2 3 var [变量名] : [类型] = 值;var uname: string = 'jack' var uname: string;
类型断言(type assertion) 类型断言可以手动指定一个值得类型,即允许变量从一种类型更改为另一种类型.
1 2 3 4 5 6 7 8 9 10 interface Foo { bar: number; bas: string; } const foo = {} as Foo;foo.bar = 123 ; foo.bas = 'hello' ;
类型推断 当类型没有指定时,TypeScript 编译器会利用类型推断来推断类型.
如果由于缺乏声明而不能推断出类型,那么它的类型被视作默认的动态 any 类型.
1 2 var num = 2 ;num = '12' ;
变量作用域
全局作用域(全局变量)
类作用域(类变量,静态变量)
局部作用域(局部变量)
1 2 3 4 5 6 7 8 9 10 11 12 var global_num = 12 class Numbers { num_val = 13 ; static sval = 10 ; storeNum(): void { var local_num = 14 ; } } console .log('全局变量为' +global_num)console .log(Numbers.sval)var obj = new Numbers()console .log('类变量' +obj.num_val)
函数 函数返回值 1 2 3 4 function greet ( ):string { return 'helloworld' }
函数参数 1 2 3 function add (x:number,y:number ): number { return x + y }
可选参数 1 2 3 4 5 6 7 8 9 10 function buildName (firstName:string,lastName ?:string ) { if (lastName){ return firstName + ' ' + lastName }else { return firstName } } let result1 = buildName('bob' ) let result2 = buildName('bob' ,'jack' ,'adams' ) let result2 = buildName('bob' ,'jack' )
默认参数 1 2 3 function caculate (price:number,rate:number = 0.50 ) { return price * rate }
剩余参数 1 2 3 function buildName (firstName: string, ...restName:string[] ) { return firstName + ' ' + restName.join(' ' ) }
lambda 箭头函数 1 var foo = (x:number ) => 10 + x
联合类型 可以通过管道符|
将变量设置多种类型.赋值时可以根据设置的类型来赋值,也可以将联合类型作为函数参数使用.
1 2 3 4 5 var val:string|numberval = 12 val = 'jack' var arr:number[] | string[]
交叉类型 你可以通过&
交叉类型从两个对象中创建一个新对象,新对象会拥有着两个对象所有的功能。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 function extend <T , U >(first: T, second: U ): T & U { const result = <T & U > {}; for (let id in first) { (<T>result)[id] = first[id]; } for (let id in second) { if (!result.hasOwnProperty(id)) { (<U>result)[id] = second[id]; } } return result; } const x = extend({ a: 'hello' }, { b: 42 }); // 现在 x 拥有了 a 属性与 b 属性 const a = x.a; const b = x.b;
TypeScript 接口 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 interface IPerson{ firstName: string, readonly lastName:string, sayHi: () => string, age?:number, [propName:string]: any } var customer: IPerson = { firstName: 'Tom' , lastName: 'Hanks' , sayHi: ():string => { return 'hi' } } interface SearchFunc{ (source: string, subString :string):boolean; } let mySearch: SearchFunc;mySearch = function (source:string,subString:string ) { return source.search(subString) !== -1 ; } interface StringArray{ [index:number]: string } let MyArray : StringArray;MyArray = ['初春令月' ,'气淑风和' ] console .log(MyArray[1 ])interface Shape{ color: string } interface PenStroke{ penWidth:nubmer } interface Square extends Shape,PenStroke{ sideLength:number } let s = <Square > {};s.color="blue" s.penWidth =100 s.sideLength = 10 // 接口还可以继承类 class Point{ x:number; y:number; } interface Point3d extend Point{ z:number; } let point3d : Point3d{ x:1, y:2, z:3 }
内联类型注解 内联类型能为你快速的提供一个类型注解。它可以帮助你省去为类型起名的麻烦,如果多次使用相同的内联注解时,可以考虑把它重构为一个接口.
1 2 3 4 5 6 7 8 9 let name: { first: string; second: string; }; name = { first: 'John' , second: 'Doe' };
TypeScript 类 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 class Car { engine: string; _name: string; constructor (engine:string){ this .engine = engine } get name():string{ return this ._name } set name(value:string){ this ._name = value } disp():void { console .log("发动机为:" + this .engine) } } class Feature extends Car { static name: string; constructor (){ super () } run():void { console .log('品牌是:' +Feature.name) } } var obj = new Car('XXSY1' )abstrct class xxx {...} interface Light{ lightOn() lightOff() } class Car implements Light { lightOn() lightOff() }
模块 TypeScript 文件模块支持commonjs, amd, es modules, others,你可以根据不同的 module
选项来把 TypeScript 编译成不同的 JavaScript 模块类型.
1 2 3 4 5 6 export interface SomeInterface{ } import {SomeInterfaceRef} from './SomeInterface'
泛型 泛型是在定义函数,接口或类时,不预先指定具体类型,而是在使用时再指定的一种特性.
使用泛型来创建可重用的组件,一个组件可以支持多种数据类型.这样用户就可以以自己的数据类型来使用组件.
1 2 3 4 5 function Hello <T >(arg:T ):T { return arg } let output = Hello<string>('helloworld' )let output2 = Hello('helloworld' )
泛型约束是在函数内部使用泛型变量时,由于事先不知道它是哪种类型,所以不能随意的操作它的属性和方法,比如 length 属性.
1 2 3 4 5 6 7 8 interface Lengthwise { length: number } function loggin <T extends Lengthwise >(arg:T ):T { console .log(arg.length) return arg }
接口可以定义函数形状,那么有泛型的接口也可以定义函数形状
1 2 3 interface CreateArrayFunc<T>{ (length:number,value :T): Array <T> }
泛型类(当实际参数也无法推测出类型时,我们还可以给泛型指定默认参数)
1 2 3 4 class GenericNumber <T =string> { zeroValue: T; add: (x:T,y:T ) => T; }
声明合并 如果声明了两个以上的 相同名字的函数,接口或类,那么它们会合并成一个类型.
函数合并 我们可以使用函数重载定义多个函数类型
1 2 3 4 5 6 7 8 9 function reverse (x:number ):number ;function reverse (x:string ):string ;function reverse (x:number | string ):number | string { if (typeof x === 'number' ){ return Number (x.toString().split('' ).reverse().join('' )) }else if (typeof x === 'string' ){ return x.split('' ).reverse().join('' ) } }
接口合并 接口合并的类型要一致,否则会报错,接口中方法合并和函数合并一样.类合并和接口合并规则一样
1 2 3 4 5 6 7 8 9 10 11 interface Alarm { price: number; } interface Alarm { weight: number; } interface Alarm { price: number; weight: number; }
声明文件 1 2 3 4 5 6 7 8 9 10 11 12 declare var jQuery: (selector: string ) => any jQuery('#foo' ) declare var declare function // 全局函数 declare class // 全局类declare enum // 全局枚举declare namespace // 全局对象(含子属性 )interface // 全局接口type // 全局类型
命名空间 TypeScript 提供了 namespace
关键字用来在确保创建的变量不会泄漏至全局变量中.
1 2 3 4 5 6 7 8 9 10 11 12 namespace Utility { export function log (msg ) { console .log(msg); } export function error (msg ) { console .log(msg); } } Utility.log('Call me' ); Utility.error('maybe' );
namespace
关键字通过 TypeScript 编译后,与我们看到的 JavaScript 代码一样:
1 2 3 (function (Utility ) { })(Utility || Utility = {});